Skip to content

fix: make asynchronous viewer actions accessible and nested-safe - #264

Draft
seonghobae wants to merge 86 commits into
mainfrom
fix/accessible-async-viewer-controls
Draft

fix: make asynchronous viewer actions accessible and nested-safe#264
seonghobae wants to merge 86 commits into
mainfrom
fix/accessible-async-viewer-controls

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Accessibility objective

Improve the Clearfolio viewer demo's async-state and repeated-table-action semantics without introducing HTML parsing or losing original DOM and accessibility state. This clean PR supersedes #162, whose Jules-managed branch repeatedly reintroduced stale workflow pins, duplicated changelog sections, and an unsafe innerHTML restoration recommendation.

Changes

  • Add document-specific accessible names for Details, Status JSON, and Open viewer actions.
  • Add a reusable, documented WeakMap-backed busy-state helper that preserves original child-node identities, disabled state, aria-busy, and aria-label exactly once.
  • Support nested/repeated busy calls with depth counting and idempotent restore functions; only the final restore reinstates the original state.
  • Use textContent and node preservation (Array.from(childNodes) / replaceChildren(...)); never back up or restore innerHTML.
  • Expose operation-specific pending accessible names and prevent duplicate activation while work is pending.
  • Apply the same busy-state contract to both Details and asynchronous Status JSON; the latter announces Loading status JSON... while its evidence request is pending.
  • Add executable Node DOM tests for contextual and omitted labels, inert markup-like filenames, initially disabled controls, pre-existing and empty ARIA values, nested calls, duplicate restores, original node identity, pending/restored behavior, and the operation-specific Status JSON pending label.
  • Run those tests during Maven test with exact 100% line, branch, and function coverage thresholds for the production DOM helper.
  • Pin Node.js 24 through a full-SHA actions/setup-node step.
  • Consolidate the duplicate Unreleased changelog section and update the accessibility engineering journal.
  • Reconcile the product change with current protected main while preserving the PDF.js integration contract.
  • Remove the one-off reconciliation workflow after GitHub Advanced Security correctly flagged its write-scoped token; the addressed thread is resolved and the privileged workflow is absent from the final diff.

Exact-head evidence

Exact current head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a is based on current protected main at f3cc09a9838f0f88c81a2ceae22138fab80a2edb. Relative to previously validated head b3453021182e99337e67d8b57a237f7196bd4e53, it changes only src/main/resources/static/assets/viewer/demo.js and src/test/js/demo-integration.test.mjs, with two replacement lines in each file to make and verify the Status JSON pending name operation-specific.

Exact-head CI run 30977565425, Security Scan run 30977565430, SAST Semgrep run 30977565499, and fuzz run 30977565442 completed successfully. CodeRabbit's exact-head inspection found no source-level blocker and the legacy CodeRabbit status is successful. All review threads are resolved or outdated. The independent repository approval and any still-running required organization check such as strix remain merge gates.

Merge gate

Do not merge until every exact-head required check, including strix when required by the organization ruleset, is successful and an independent approving reviewer with repository write access is present. Every branch-protection, security, accessibility, coverage, and repository-policy gate must remain satisfied for 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 92feaf32-e265-4038-bd57-d40b18f46c77

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 81c2c7f0cc8326e049429ef99ef64a9fa40f77b4. This one-commit branch supersedes the mutable Jules branch #162. Verify the nested-safe WeakMap busy-state contract, exact DOM/ARIA restoration, contextual accessible names, inert markup-like labels, executable Node tests, 100% line/branch/function coverage for the production helper, Java test/Javadoc gates, and all repository protections. Submit APPROVE only after exact-head CI, Security Scan, SAST, and fuzzing are complete and clean.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

@seonghobae I will review pull request #264 at the specified commit.

I will check the busy-state contract, DOM and ARIA restoration, accessible names, test coverage, and required repository checks. I will not approve the pull request until the exact-head checks and required protections are complete and clean.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@seonghobae
seonghobae enabled auto-merge (squash) August 5, 2026 02:27

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Copy link
Copy Markdown
Collaborator Author

@opencode-agent Please independently review exact current head 81c2c7f0cc8326e049429ef99ef64a9fa40f77b4. This clean PR supersedes #162 and is one commit on the protected main baseline. Exact-head CI, Security Scan, SAST Semgrep, and fuzzing are successful. Verify the shared WeakMap busy-state contract, consumer import, contextual accessible names, inert text handling, Node 100% line/branch/function gate, changelog consolidation, and repository protection evidence before approval.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@cwl-noema-review Please independently review exact current head 81c2c7f0cc8326e049429ef99ef64a9fa40f77b4. This clean one-commit PR supersedes #162 and exact-head CI, Security Scan, SAST Semgrep, and fuzzing are successful. Verify the production consumer import, WeakMap depth/idempotence contract, exact restoration of DOM/disabled/ARIA state, contextual inert labels, Node 100% line/branch/function gate, documentation, and repository protections. Submit APPROVE only for this exact head if no blocker remains.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe. CI, Security Scan, SAST Semgrep, and fuzzing are successful on this head. Verify the shared WeakMap state contract, production consumer import, contextual and inert labels, exact DOM/disabled/ARIA restoration, full-SHA Node.js 24 pin, Node 100% line/branch/function gate, documentation, and repository protections. Submit APPROVE only for this exact head if no blocker remains.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

@seonghobae I will review pull request #264 at exact head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe. I will verify the requested implementation and check requirements before I approve it.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent @cwl-noema-review Please independently review exact current head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe. Exact-head CI, Node 24 executable DOM tests with 100% dom-utils.js line/branch/function coverage, Security Scan, SAST Semgrep, fuzzing, and CodeRabbit all succeed. Verify document-specific action names, original child-node identity preservation, exact disabled/ARIA restoration, nested/idempotent WeakMap busy state, markup-like filename inertness, duplicate-activation prevention, Java/JaCoCo preservation, pinned Actions, consolidated CHANGELOG, and accessibility doctoring. Submit APPROVE only if no blocker remains.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe. Current-head CI, Security Scan, SAST Semgrep, and fuzz are successful. Verify the WeakMap depth-counted busy-state contract, idempotent and exact DOM/disabled/ARIA restoration, inert treatment of markup-like document names, operation-specific accessible names, duplicate-activation prevention, Node 24 full-SHA workflow pin, and exact 100% line/branch/function coverage for dom-utils.js. Submit APPROVE only for this exact head after all repository protections pass.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='734a72686f5671f757cd9f2a6e1fec0ecc93d1fe'

printf '%s\n' '== Local commit and changed files =='
git rev-parse HEAD
git diff --name-status "${expected}^" "${expected}"
git diff --stat "${expected}^" "${expected}"

printf '%s\n' '== JavaScript and build/workflow candidates =='
fd -t f . | rg '(^|/)(dom-utils\.js|.*dom.*test.*\.(js|mjs|cjs)|pom\.xml|CHANGELOG.*|.*journal.*|.*accessib.*|.*\.ya?ml)$' || true

printf '%s\n' '== Source outlines =='
while IFS= read -r f; do
  case "$f" in
    *.js|*.mjs|*.cjs)
      echo "--- $f"
      ast-grep outline "$f" --items all || true
      ;;
  esac
done < <(git diff --name-only "${expected}^" "${expected}" | rg '\.(js|mjs|cjs)$' || true)

printf '%s\n' '== Changed diff =='
git diff --find-renames --find-copies "${expected}^" "${expected}"

printf '%s\n' '== GitHub PR, checks, and protection metadata =='
gh pr view 264 --repo ContextualWisdomLab/clearfolio --json number,headRefOid,baseRefName,state,isDraft,mergeStateStatus,reviewDecision,statusCheckRollup,url
gh api 'repos/ContextualWisdomLab/clearfolio/commits/734a72686f5671f757cd9f2a6e1fec0ecc93d1fe/check-runs?per_page=100' \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`' || true
gh api 'repos/ContextualWisdomLab/clearfolio/branches/main/protection' || true

Length of output: 2177


🏁 Script executed:

#!/bin/bash
set -u

repo='ContextualWisdomLab/clearfolio'
sha='734a72686f5671f757cd9f2a6e1fec0ecc93d1fe'

echo '== Pull request metadata =='
gh pr view 264 --repo "$repo" --json number,headRefOid,baseRefName,baseRefOid,state,isDraft,mergeStateStatus,reviewDecision,statusCheckRollup,url || true

echo '== Pull request file list =='
gh pr diff 264 --repo "$repo" --name-only || true

echo '== Merge base and full pull request changed files =='
base="$(git merge-base HEAD origin/main 2>/dev/null || true)"
printf 'merge-base=%s\n' "$base"
if [ -n "$base" ]; then
  git diff --name-status "$base" HEAD
fi

echo '== dom-utils.js outline and content =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all || true
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,320p' || true

echo '== Node DOM test content =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,420p' || true

echo '== Maven Node test and coverage configuration =='
rg -n -C 12 'dom-utils|node|coverage|nyc|c8|exec-maven|frontend' pom.xml || true

echo '== CI Node setup configuration =='
nl -ba .github/workflows/ci.yml | sed -n '1,260p' || true

echo '== Production consumers and accessible action labels =='
rg -n -C 8 'setBusy|busy|Details|Status JSON|Open viewer|aria-label|disabled' src/main/resources/static || true

echo '== Changelog and accessibility documentation changes from merge base =='
if [ -n "$base" ]; then
  git diff --unified=40 "$base" HEAD -- CHANGELOG.md docs || true
fi

Length of output: 45940


🏁 Script executed:

#!/bin/bash
set -u

repo='ContextualWisdomLab/clearfolio'
base='8e2d36f260395dbd0304abc503d8bd15ffcf8dab'
head='734a72686f5671f757cd9f2a6e1fec0ecc93d1fe'

echo '== Complete helper implementation =='
sed -n '1,180p' src/main/resources/static/assets/viewer/dom-utils.js || true

echo '== Complete executable Node DOM test =='
sed -n '1,460p' src/test/js/dom-utils.test.mjs || true

echo '== Relevant production consumer implementation =='
sed -n '100,155p' src/main/resources/static/assets/viewer/demo.js || true
sed -n '250,520p' src/main/resources/static/assets/viewer/demo.js || true

echo '== Complete CI workflow =='
sed -n '1,300p' .github/workflows/ci.yml || true

echo '== Focused base-to-head diffs =='
git diff --check "$base" "$head" || true
git diff --unified=20 "$base" "$head" -- \
  .github/workflows/ci.yml pom.xml \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs || true

echo '== Pin format checks =='
rg -n -P 'uses:\s*actions/setup-node@|node-version:|node-version-file:' .github/workflows/ci.yml || true

echo '== Required reviews and branch protection =='
gh pr view 264 --repo "$repo" --json latestReviews,reviewRequests,reviewDecision,mergeStateStatus || true
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 57297


@seonghobae Review complete for exact head 734a72686f5671f757cd9f2a6e1fec0ecc93d1fe.

Blocking finding: src/main/resources/static/assets/viewer/demo.js Line 135 creates the Status JSON button without setBusyState. openJsonDocument() is asynchronous. While its fetch is pending, users can activate the button again and open additional popup windows. The action also has no pending accessible name.

Apply setBusyState to this handler and restore it after openJsonDocument() settles. Use an operation-specific pending label, such as Loading status JSON....

I verified the shared WeakMap helper, exact DOM/ARIA restoration, node identity preservation, inert text handling, Node 24 full-SHA pin, Maven coverage thresholds, and successful exact-head checks. I did not approve because this blocker remains. GitHub also reports REVIEW_REQUIRED and BLOCKED; the repository ruleset requires one approving review.

You are interacting with an AI system.

seonghobae added a commit that referenced this pull request Aug 5, 2026
This branch has been superseded by a cleaner replacement PR (#264).
No further work will be performed on this branch.
Comment thread .github/workflows/verify-demo-integration.yml Fixed
@opencode-agent
opencode-agent Bot disabled auto-merge August 5, 2026 03:17

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 347203d5dc7b6bd4a53877f322bbaba28acb527f. The current-head CI, Security Scan, SAST Semgrep, and fuzz workflows all succeed. The prior CI failure was traced to the executable integration test's DOM double incorrectly manufacturing an empty text node for textContent = ""; the current head now models browser child-removal semantics and preserves exact 100% line, branch, and function coverage for dom-utils.js. Verify the WeakMap depth-counted busy-state contract, idempotent exact DOM/disabled/ARIA restoration, contextual inert document labels, duplicate-activation prevention, full-SHA Node.js 24 pin, test-double fidelity, documentation, and repository protections. Submit APPROVE only for this exact head if no blocker remains.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'

echo '== Exact head and PR metadata =='
printf 'local HEAD: '; git rev-parse HEAD
git show -s --format='commit: %H%nparents: %P%nsubject: %s' "$sha"
gh pr view 264 --repo "$repo" \
  --json number,url,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Pull request diff summary =='
base="$(git merge-base "$sha" origin/main)"
printf 'merge-base: %s\n' "$base"
git diff --check "$base" "$sha"
git diff --name-status "$base" "$sha"

echo '== Relevant source outlines =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all

echo '== Busy helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,260p'

echo '== Viewer consumers and accessible labels =='
rg -n -C 10 -P '\b(setBusyState|openJsonDocument|openViewer|Details|Status JSON|Open viewer|aria-label|aria-busy|disabled)\b' \
  src/main/resources/static/assets/viewer/demo.js

echo '== DOM helper tests and test-double semantics =='
rg -n -C 10 -P '(textContent|childNodes|replaceChildren|setBusyState|nested|restore|aria-busy|aria-label|disabled)' \
  src/test/js/dom-utils.test.mjs

echo '== Maven test and coverage configuration =='
rg -n -C 12 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node setup pin =='
rg -n -C 4 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Documentation changes =='
git diff --unified=20 "$base" "$sha" -- CHANGELOG.md docs

echo '== Exact-commit checks =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name, .status, .conclusion, .details_url] | `@tsv`'

echo '== Branch protection and rules =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 15907


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'
base='8e2d36f260395dbd0304abc503d8bd15ffcf8dab'

echo '== Helper implementation =='
sed -n '1,180p' src/main/resources/static/assets/viewer/dom-utils.js

echo '== Async viewer actions =='
sed -n '75,150p' src/main/resources/static/assets/viewer/demo.js
sed -n '220,310p' src/main/resources/static/assets/viewer/demo.js

echo '== DOM helper tests =='
sed -n '1,360p' src/test/js/dom-utils.test.mjs

echo '== Integration test and DOM double =='
sed -n '1,420p' src/test/js/demo-integration.test.mjs

echo '== Maven Node test and coverage gate =='
grep -n -E -C 12 'dom-utils|node|c8|coverage|line|branch|function|exec-maven' pom.xml || true

echo '== CI Node setup =='
grep -n -E -C 4 'actions/setup-node@|node-version:' .github/workflows/ci.yml || true

echo '== Exact relevant diff =='
git diff --check "$base" "$sha"
git diff --unified=30 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md .jules/palette.md \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs src/test/js/demo-integration.test.mjs

echo '== Current exact-head check states =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | select(.name == "strix" or .name == "Maven test" or .name == "Semgrep (multi-language SAST)" or .name == "osv-scan" or .name == "fuzz (ArtifactTokenParserFuzzTest)") | [.name,.status,.conclusion] | `@tsv`'

echo '== Required branch protection =='
gh api "repos/$repo/branches/main/protection/required_status_checks" || true
gh api "repos/$repo/branches/main/protection/required_pull_request_reviews" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 76067


@seonghobae Review complete for exact head 347203d5dc7b6bd4a53877f322bbaba28acb527f.

Blocking finding: The Status JSON action in src/main/resources/static/assets/viewer/demo.js still calls asynchronous openJsonDocument() without setBusyState.

A user can activate this action again before fetchJson() completes. This can open more popup windows. The action also has no pending accessible name.

Apply the shared helper in this handler. Restore the state when openJsonDocument() settles. Use an operation-specific pending label such as Loading status JSON....

I verified the WeakMap depth and idempotence contract, exact DOM and ARIA restoration, original child-node preservation, contextual inert labels, integration test DOM semantics for textContent = "", Node 24 full-SHA setup pin, Maven Node coverage thresholds, changelog consolidation, and journal documentation.

I did not approve this PR. The source blocker remains. The exact-head strix check is also still in progress. GitHub reports the PR as blocked and requires an approval. The branch-protection REST endpoints returned 403, but the available ruleset data shows the required organization workflows and one required approving review.


✏️ Learnings added
Learnt from: seonghobae
URL: https://github.com/ContextualWisdomLab/clearfolio/pull/264

Timestamp: 2026-08-05T03:30:42.098Z
Learning: In `src/test/js/demo-integration.test.mjs`, the `MockElement.textContent` setter must model browser semantics: assigning `textContent = ""` removes all child nodes rather than creating an empty text node. This behavior is necessary for executable viewer integration tests that verify rendered DOM structure.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 347203d5dc7b6bd4a53877f322bbaba28acb527f. CI, Security Scan, SAST Semgrep, and fuzzing all succeeded on this head. Verify the production demo.js consumer import, WeakMap nesting/idempotence contract, exact DOM/disabled/ARIA restoration, inert contextual labels, executable non-empty-history integration test, full-SHA Node.js 24 pin, 100% Node line/branch/function gate, documentation, and repository protections. Submit approval only for this exact head if no blocker remains.

@seonghobae
seonghobae enabled auto-merge (squash) August 5, 2026 03:32

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 347203d5dc7b6bd4a53877f322bbaba28acb527f. Exact-head CI run 30972309198, Security Scan 30972309188, SAST Semgrep 30972309203, and fuzz 30972309205 are successful. Verify WeakMap depth-counted busy-state behavior, exact and idempotent DOM/disabled/ARIA restoration, inert markup-like filenames, operation-specific accessible names, duplicate-activation prevention, full-SHA Node 24 workflow pinning, demo-module integration, and exact 100% line/branch/function coverage for dom-utils.js. Submit APPROVE only for this exact head and only if all repository protections remain satisfied.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'

echo '== Exact commit and pull request =='
printf 'local HEAD: '; git rev-parse HEAD
git show -s --format='commit: %H%nparents: %P%nsubject: %s' "$sha"
gh pr view 264 --repo "$repo" \
  --json number,url,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Merge base and changed files =='
base="$(git merge-base "$sha" origin/main)"
printf 'merge-base: %s\n' "$base"
git diff --check "$base" "$sha"
git diff --name-status "$base" "$sha"

echo '== Relevant source maps =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all
ast-grep outline src/test/js/demo-integration.test.mjs --items all

echo '== Busy helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,260p'

echo '== Async action consumers and accessible labels =='
rg -n -C 12 -P '\b(setBusyState|openJsonDocument|openViewer|openDocumentDetails|Details|Status JSON|Open viewer|aria-label|aria-busy|disabled)\b' \
  src/main/resources/static/assets/viewer/demo.js

echo '== Unit and integration tests =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,460p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '1,520p'

echo '== Maven coverage configuration =='
rg -n -C 14 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node setup action pin =='
rg -n -C 5 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Focused diff and documentation =='
git diff --unified=35 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md .jules/palette.md \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs src/test/js/demo-integration.test.mjs

echo '== Exact-head check runs =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Repository protection and rules =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 16589


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'
base="$(git merge-base "$sha" origin/main)"

echo '== Busy helper =='
sed -n '1,180p' src/main/resources/static/assets/viewer/dom-utils.js

echo '== Demo imports, JSON action, viewer actions, and history rendering =='
sed -n '1,160p' src/main/resources/static/assets/viewer/demo.js
sed -n '220,310p' src/main/resources/static/assets/viewer/demo.js
sed -n '400,565p' src/main/resources/static/assets/viewer/demo.js

echo '== Busy helper tests =='
sed -n '1,460p' src/test/js/dom-utils.test.mjs

echo '== Demo integration test =='
sed -n '1,540p' src/test/js/demo-integration.test.mjs

echo '== Maven Node execution and coverage gate =='
rg -n -C 16 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== CI Node pin =='
sed -n '1,260p' .github/workflows/ci.yml
rg -n -P 'uses:\s*actions/setup-node@[0-9a-f]{40}|node-version:\s*["'\'']?24' .github/workflows/ci.yml

echo '== Changelog and accessibility documentation diff =='
git diff --unified=30 "$base" "$sha" -- CHANGELOG.md .jules/palette.md

echo '== Full relevant source and test diff =='
git diff --check "$base" "$sha"
git diff --unified=35 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs src/test/js/demo-integration.test.mjs

echo '== Current exact-head check runs =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion] | `@tsv`'

echo '== Pull-request reviews and merge state =='
gh pr view 264 --repo "$repo" --json headRefOid,mergeStateStatus,reviewDecision,latestReviews

echo '== Branch protection and rulesets =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 88657


@seonghobae Review complete for exact head 347203d5dc7b6bd4a53877f322bbaba28acb527f.

Blocking finding: src/main/resources/static/assets/viewer/demo.js creates the Status JSON button without setBusyState.

openJsonDocument() is asynchronous because it awaits fetchJson(). While that request is pending, the button remains enabled. A user can activate it again and open additional popup windows. The action also has no operation-specific pending accessible name.

Apply the shared helper in this handler. Restore the state when openJsonDocument() settles. Use a pending label such as Loading status JSON....

The shared helper otherwise implements the required WeakMap depth counting, idempotent restore callbacks, exact disabled and ARIA restoration, and original child-node preservation. The tests cover the helper contract and the non-empty-history inert-label integration case. Maven enforces 100% line, branch, and function coverage for dom-utils.js. The Node.js 24 setup action uses a full commit SHA. The changelog and engineering journal changes are consistent with the implementation.

I did not approve this PR. The Status JSON source blocker remains. The exact-head strix check is also still in_progress. GitHub reports REVIEW_REQUIRED and BLOCKED. The available repository rules require one approval.

You are interacting with an AI system.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'

echo '== Exact head and pull request state =='
printf 'local HEAD: '; git rev-parse HEAD
git show -s --format='commit: %H%nparents: %P%nsubject: %s' "$sha"
gh pr view 264 --repo "$repo" \
  --json number,url,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Merge-base diff and whitespace check =='
base="$(git merge-base "$sha" origin/main)"
printf 'merge-base: %s\n' "$base"
git diff --check "$base" "$sha"
git diff --name-status "$base" "$sha"

echo '== Source outlines =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all
ast-grep outline src/test/js/demo-integration.test.mjs --items all

echo '== Busy helper and async action consumers =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,240p'
rg -n -C 12 -P '\b(setBusyState|openJsonDocument|openViewer|fetchJson|Details|Status JSON|Open viewer|aria-label|aria-busy|disabled)\b' \
  src/main/resources/static/assets/viewer/demo.js

echo '== Helper and integration tests =='
rg -n -C 12 -P '(setBusyState|nested|restore|textContent|childNodes|replaceChildren|aria-busy|aria-label|disabled|markup)' \
  src/test/js/dom-utils.test.mjs src/test/js/demo-integration.test.mjs

echo '== Maven test and coverage contract =='
rg -n -C 14 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node setup pin =='
rg -n -C 5 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Documentation diff =='
git diff --unified=20 "$base" "$sha" -- CHANGELOG.md docs .jules/palette.md

echo '== Exact commit check runs =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Required review and workflow rules =='
gh api "repos/$repo/branches/main/protection/required_pull_request_reviews" || true
gh api "repos/$repo/branches/main/protection/required_status_checks" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 16550


🏁 Script executed:

#!/bin/bash
set -u

repo='ContextualWisdomLab/clearfolio'
sha='347203d5dc7b6bd4a53877f322bbaba28acb527f'
base='8e2d36f260395dbd0304abc503d8bd15ffcf8dab'

numbered() {
  awk '{ printf "%6d\t%s\n", NR, $0 }' "$1"
}

echo '== Busy helper =='
numbered src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,220p' || true

echo '== Demo imports and async action handlers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '1,155p' || true
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '215,310p' || true
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '425,555p' || true

echo '== All helper calls and async functions in demo =='
rg -n -C 8 -P '\b(setBusyState|openJsonDocument|openJobDetail|retryActiveJob|refreshKpis|refreshKpiEvidence|loadDemoData|submitDocument)\s*\(' \
  src/main/resources/static/assets/viewer/demo.js || true

echo '== DOM helper tests =='
numbered src/test/js/dom-utils.test.mjs | sed -n '1,380p' || true

echo '== Demo module integration test =='
numbered src/test/js/demo-integration.test.mjs | sed -n '1,480p' || true

echo '== Maven Node test and coverage contract =='
rg -n -C 16 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml || true

echo '== Full-SHA Node.js workflow pin =='
rg -n -C 6 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml || true

echo '== Focused product diff =='
git diff --unified=30 "$base" "$sha" -- \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs \
  src/test/js/demo-integration.test.mjs \
  pom.xml .github/workflows/ci.yml || true

echo '== Documentation diff =='
git diff --unified=20 "$base" "$sha" -- CHANGELOG.md docs .jules/palette.md || true

echo '== Current exact-head checks =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | select(.name == "Maven test" or .name == "strix" or .name == "Semgrep (multi-language SAST)" or .name == "osv-scan" or (.name | startswith("fuzz"))) | [.name,.status,.conclusion] | `@tsv`' || true

echo '== Pull request reviews and rules =='
gh pr view 264 --repo "$repo" --json headRefOid,mergeStateStatus,reviewDecision,latestReviews,reviewRequests || true
gh api "repos/$repo/branches/main/protection/required_pull_request_reviews" || true
gh api "repos/$repo/branches/main/protection/required_status_checks" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 98573


@seonghobae Review complete for exact head 347203d5dc7b6bd4a53877f322bbaba28acb527f.

Blocking finding: src/main/resources/static/assets/viewer/demo.js Line 135 starts asynchronous openJsonDocument() without setBusyState.

A user can activate Status JSON again while fetchJson() is pending. Each activation can open another popup. The control also has no operation-specific pending accessible name.

Apply the shared helper in this handler. Restore the state when openJsonDocument() settles. Use a pending label such as Loading status JSON....

I verified the following items:

  • setBusyState uses a WeakMap and depth counting.
  • Restore callbacks are idempotent.
  • The helper preserves original child-node identity.
  • The helper restores disabled, aria-busy, and aria-label exactly.
  • Repeated actions have contextual accessible names.
  • Markup-like filenames use textContent and remain inert.
  • The production demo.js integration test verifies a non-empty history row.
  • Maven runs the Node tests with exact 100% line, branch, and function thresholds for dom-utils.js.
  • The workflow pins actions/setup-node by full SHA and selects Node.js 24.
  • The changelog has one Unreleased section. The engineering journal documents the shared pattern.

I did not approve this pull request. The Status JSON blocker remains. The exact-head strix check is also still in progress. GitHub reports BLOCKED and REVIEW_REQUIRED. The available ruleset requires one approving review. The branch-protection REST endpoints returned 403, so I could not verify their full configuration.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 6d37f2150d527626b9646fccd0d5bf8327ace7cb. The prior Status JSON blocker is addressed: its asynchronous handler now applies setBusyState immediately, disables repeated activation, exposes Loading... View status JSON for <document> while pending, and restores the exact original DOM/disabled/ARIA state in finally. The executable production-module integration test holds the request pending, asserts the busy state and popup safety, resolves JSON, then asserts exact restoration and rendered evidence. Exact-head CI, Security Scan, SAST Semgrep, and fuzzing all succeed. Verify the complete nested-safe contract, operation coverage, inert filename handling, popup behavior, full-SHA Node.js pin, 100% helper coverage, documentation, and repository protections. Submit APPROVE only for this exact head if no blocker remains.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='6d37f2150d527626b9646fccd0d5bf8327ace7cb'

echo '== Exact commit and pull request =='
printf 'local HEAD: '; git rev-parse HEAD
git show -s --format='commit: %H%nparents: %P%nsubject: %s' "$sha"
gh pr view 264 --repo "$repo" \
  --json number,url,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Merge-base diff =='
base="$(git merge-base "$sha" origin/main)"
printf 'merge-base: %s\n' "$base"
git diff --check "$base" "$sha"
git diff --name-status "$base" "$sha"

echo '== Relevant source outlines =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all
ast-grep outline src/test/js/demo-integration.test.mjs --items all

echo '== Busy helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,260p'

echo '== Viewer action consumers =='
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '1,180p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '215,330p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '420,580p'

echo '== Busy-state and integration tests =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,480p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '1,560p'

echo '== Maven test and coverage configuration =='
rg -n -C 14 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node setup configuration =='
rg -n -C 6 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Focused product and documentation diff =='
git diff --unified=35 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md docs .jules/palette.md \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs \
  src/test/js/demo-integration.test.mjs

echo '== Exact-head check runs =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Available protection and ruleset data =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 16618


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='6d37f2150d527626b9646fccd0d5bf8327ace7cb'
base='8e2d36f260395dbd0304abc503d8bd15ffcf8dab'

numbered() {
  awk '{ printf "%6d\t%s\n", NR, $0 }' "$1"
}

echo '== Busy-state helper =='
numbered src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,240p'

echo '== Demo imports and Status JSON action =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '1,170p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '215,320p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '420,575p'

echo '== Helper tests =='
numbered src/test/js/dom-utils.test.mjs | sed -n '1,460p'

echo '== Production-module integration test =='
numbered src/test/js/demo-integration.test.mjs | sed -n '1,560p'

echo '== Maven execution and coverage thresholds =='
rg -n -C 16 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Node.js setup pin =='
rg -n -C 6 -P '(actions/setup-node@|node-version:)' .github/workflows/ci.yml

echo '== Focused diff and documentation =='
git diff --check "$base" "$sha"
git diff --unified=35 "$base" "$sha" -- \
  .github/workflows/ci.yml pom.xml CHANGELOG.md .jules/palette.md docs \
  src/main/resources/static/assets/viewer/demo.js \
  src/main/resources/static/assets/viewer/dom-utils.js \
  src/test/js/dom-utils.test.mjs \
  src/test/js/demo-integration.test.mjs

echo '== Current exact-head checks =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | select(.name == "Maven test" or .name == "strix" or .name == "Semgrep (multi-language SAST)" or .name == "osv-scan" or (.name | startswith("fuzz"))) | [.name,.status,.conclusion] | `@tsv`'

echo '== Pull request state and available protection data =='
gh pr view 264 --repo "$repo" --json headRefOid,mergeStateStatus,reviewDecision,latestReviews
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true

Length of output: 94832


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
sha='6d37f2150d527626b9646fccd0d5bf8327ace7cb'

echo '== Current exact-head required workflow states =='
gh api "repos/$repo/commits/$sha/check-runs?per_page=100" --paginate \
  --jq '.check_runs[]
    | select(
        .name == "Maven test"
        or .name == "strix"
        or .name == "Semgrep (multi-language SAST)"
        or .name == "osv-scan"
        or (.name | startswith("fuzz"))
      )
    | [.name, .status, .conclusion]
    | `@tsv`'

echo '== Pull request head and merge state =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Available main branch protection =='
gh api "repos/$repo/branches/main/protection" || true

echo '== Available main branch rulesets =='
gh api "repos/$repo/rules/branches/main" || true

Length of output: 14024


@seonghobae Review complete for exact head 6d37f2150d527626b9646fccd0d5bf8327ace7cb.

I found no new source-level blocker.

The prior Status JSON finding is fixed. demo.js applies setBusyState before openJsonDocument() starts. It restores state through .finally(restore). The pending accessible name is Loading... View status JSON for <document>. The control is disabled while the request is pending.

I verified these items:

  • setBusyState uses a WeakMap, depth counting, and idempotent restore callbacks.
  • The helper preserves original child-node identities.
  • The helper restores disabled, aria-busy, and aria-label exactly.
  • Details, Status JSON, and Open viewer have document-specific accessible names.
  • textContent keeps markup-like filenames inert.
  • The production-module integration test verifies pending and restored Status JSON state, popup opener isolation, rendered JSON, and browser-like textContent = "" child removal.
  • Maven runs the Node tests during test.
  • Maven enforces 100% line, branch, and function coverage for src/main/resources/static/assets/viewer/dom-utils.js.
  • CI uses Node.js 24 and pins actions/setup-node to a full SHA.
  • The changelog has one Unreleased section. The engineering journal documents the shared contract.

I cannot approve yet. The exact-head strix check is still in_progress. GitHub reports BLOCKED and REVIEW_REQUIRED. The available rulesets also require the organization workflows, resolved review threads, and one repository approval. The branch-protection API returned HTTP 403, so its full configuration could not be verified.

You are interacting with an AI system.

@seonghobae
seonghobae marked this pull request as draft August 5, 2026 03:48
auto-merge was automatically disabled August 5, 2026 03:48

Pull request was converted to draft

@seonghobae
seonghobae marked this pull request as ready for review August 5, 2026 03:48

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a only. Verify the accessible asynchronous viewer contract: document-specific accessible names, operation-specific pending names, nested/repeated busy depth, idempotent restoration, exact preservation of child-node identity and prior disabled/ARIA state, inert treatment of markup-like filenames, duplicate-activation prevention, and executable Node DOM tests with 100% production line, branch, and function coverage. Confirm the previously flagged write-scoped reconciliation workflow is absent and no stale workflow finding remains.

Exact-head Actions are successful: CI 30977565425, Security Scan 30977565430, SAST Semgrep 30977565499, and fuzz 30977565442. Existing GitHub Advanced Security threads are resolved and outdated. Submit a formal exact-head review and APPROVE only if no blocker remains; do not treat a commit status, stale comment, or owner review as independent approval.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'
prior='b3453021182e99337e67d8b57a237f7196bd4e53'

echo '== Exact commit and PR state =='
printf 'checkout='; git rev-parse HEAD
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$head"
gh pr view 264 --repo "$repo" \
  --json number,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Exact-head delta =='
git diff --check "$prior" "$head"
git diff --name-status "$prior" "$head"
git diff --unified=35 "$prior" "$head" -- \
  src/main/resources/static/assets/viewer/demo.js \
  src/test/js/demo-integration.test.mjs

echo '== Relevant source outlines =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all
ast-grep outline src/test/js/demo-integration.test.mjs --items all

echo '== Busy-state helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,240p'

echo '== Viewer actions and accessible labels =='
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '70,170p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '215,330p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '420,590p'

echo '== Busy-state unit tests and viewer integration test =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,520p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '100,330p'

echo '== Maven Node-test and coverage configuration =='
rg -n -C 18 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Workflow inventory, pins, and privileged-workflow indicators =='
fd -t f . .github/workflows | sort
rg -n -C 5 -P '^\s*uses:|actions/setup-node@|node-version:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile' .github/workflows || true

echo '== PDF.js version contract =='
rg -n -C 3 -P '(pdfjs|pdf\.js|PDF\.js|6\.1\.200)' pom.xml src/main README.md || true

echo '== Exact-head check runs =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line | tostring),.comments.nodes[0].body]
    | `@tsv`' || true

echo '== Protection and ruleset data =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true

Length of output: 23725


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'

numbered() {
  awk '{ printf "%6d\t%s\n", NR, $0 }' "$1"
}

echo '== Busy-state helper =='
numbered src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,240p'

echo '== Viewer action consumers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '70,170p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '215,330p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '420,590p'

echo '== Busy-state unit tests =='
numbered src/test/js/dom-utils.test.mjs | sed -n '1,520p'

echo '== Production-module integration test =='
numbered src/test/js/demo-integration.test.mjs | sed -n '100,330p'

echo '== Maven Node-test and coverage configuration =='
rg -n -C 18 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Workflow inventory and relevant references =='
fd -t f . .github/workflows | sort
rg -n -C 5 -P '^\s*uses:|actions/setup-node@|node-version:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile' .github/workflows || true

echo '== PDF.js version contract =='
rg -n -C 3 -P '(pdfjs|pdf\.js|PDF\.js|6\.1\.200)' pom.xml src/main README.md || true

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login,.comments.nodes[0].path,(.comments.nodes[0].line | tostring),.comments.nodes[0].body]
    | `@tsv`' || true

echo '== Current PR state and available protection data =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,latestReviews,statusCheckRollup
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true

Length of output: 63105


@seonghobae Review complete for exact head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a.

I found no source-level blocker.

  • setBusyState uses WeakMap state and depth counting.
  • Restore callbacks are idempotent.
  • The helper restores state only after the final restore call.
  • The helper preserves original child-node identities with Array.from(button.childNodes) and replaceChildren(...).
  • The helper restores the original disabled, aria-busy, and aria-label values. It distinguishes absent and empty ARIA values.
  • Details, Status JSON, and Open viewer have document-specific accessible names.
  • Status JSON applies setBusyState before the asynchronous request. It uses Loading status JSON... and restores state in .finally(restore).
  • A disabled native button prevents repeated user activation during the pending request.
  • Filenames use textContent. The tests verify that markup-like filenames remain inert text.
  • The integration test verifies the pending Status JSON label, disabled state, aria-busy, restored state, popup opener isolation, and rendered JSON.
  • Maven runs the Node tests during test. It requires 100% line, branch, and function coverage for src/main/resources/static/assets/viewer/dom-utils.js.
  • CI uses Node.js 24 and a full-SHA actions/setup-node pin.
  • The checked workflow inventory contains no reconciliation workflow or write-scoped workflow indicator.
  • The PDF.js module and worker paths remain at version 6.1.200.
  • Maven, Security Scan, Semgrep, Strix, CodeQL, and fuzz checks succeeded for this exact head.
  • The review-thread query returned no unresolved threads.

I cannot approve this pull request. GitHub still reports BLOCKED and REVIEW_REQUIRED. The repository ruleset requires one approving repository review, and the current review list does not contain that approval. The branch-protection endpoint returned HTTP 403, so I could not inspect its complete configuration.

You are interacting with an AI system.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a. Verify the WeakMap depth-counted busy-state contract, exact child-node identity and disabled/ARIA restoration, inert handling of markup-like document names, operation-specific accessible names, duplicate-activation prevention, executable Node 24 DOM tests with 100% line/branch/function coverage for the production helper, immutable action pins, and absence of the superseded write-scoped reconciliation workflows. Exact-head CI, Security Scan, SAST, and fuzz are successful; submit formal review evidence only for this head.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'
prior='b3453021182e99337e67d8b57a237f7196bd4e53'

echo '== Exact commit and pull request state =='
printf 'checkout='; git rev-parse HEAD
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$head"
gh pr view 264 --repo "$repo" \
  --json number,state,isDraft,headRefOid,baseRefName,baseRefOid,mergeStateStatus,reviewDecision,statusCheckRollup,latestReviews

echo '== Exact-head delta and whitespace =='
git diff --check "$prior" "$head"
git diff --name-status "$prior" "$head"
git diff --unified=35 "$prior" "$head" -- \
  src/main/resources/static/assets/viewer/demo.js \
  src/test/js/demo-integration.test.mjs

echo '== Source outlines =='
ast-grep outline src/main/resources/static/assets/viewer/dom-utils.js --items all
ast-grep outline src/main/resources/static/assets/viewer/demo.js --items all
ast-grep outline src/test/js/dom-utils.test.mjs --items all
ast-grep outline src/test/js/demo-integration.test.mjs --items all

echo '== Busy-state helper =='
nl -ba src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,250p'

echo '== Viewer action consumers =='
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '65,180p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '210,340p'
nl -ba src/main/resources/static/assets/viewer/demo.js | sed -n '415,600p'

echo '== Unit and integration test assertions =='
nl -ba src/test/js/dom-utils.test.mjs | sed -n '1,540p'
nl -ba src/test/js/demo-integration.test.mjs | sed -n '90,350p'

echo '== Maven test and coverage configuration =='
rg -n -C 18 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Workflow inventory, immutable pins, and privileged indicators =='
fd -t f . .github/workflows | sort
rg -n -C 5 -P '^\s*uses:|actions/setup-node@|node-version:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile' .github/workflows || true

echo '== Exact-head check runs =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" --paginate \
  --jq '.check_runs[] | [.name,.status,.conclusion,.details_url] | `@tsv`'

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login, .comments.nodes[0].path, (.comments.nodes[0].line | tostring), .comments.nodes[0].body]
    | `@tsv`' || true

echo '== Available branch protection and rulesets =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true

Length of output: 23619


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='ContextualWisdomLab/clearfolio'
head='718107a7a6eaca15a1f3e33ea7ceebefaf23d85a'

numbered() {
  awk '{ printf "%6d\t%s\n", NR, $0 }' "$1"
}

echo '== Busy-state helper =='
numbered src/main/resources/static/assets/viewer/dom-utils.js | sed -n '1,250p'

echo '== Viewer action consumers =='
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '65,180p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '210,340p'
numbered src/main/resources/static/assets/viewer/demo.js | sed -n '415,600p'

echo '== Busy-state unit tests =='
numbered src/test/js/dom-utils.test.mjs | sed -n '1,540p'

echo '== Production integration test =='
numbered src/test/js/demo-integration.test.mjs | sed -n '90,350p'

echo '== Maven Node test and coverage configuration =='
rg -n -C 18 -P '(dom-utils|node|c8|coverage|line|branch|function|exec-maven)' pom.xml

echo '== Workflow inventory and relevant references =='
fd -t f . .github/workflows | sort
rg -n -C 5 -P '^\s*uses:|actions/setup-node@|node-version:|contents:\s*write|pull-requests:\s*write|persist-credentials:\s*true|reconcile' .github/workflows || true

echo '== Unresolved review threads =='
gh api graphql \
  -F owner='ContextualWisdomLab' -F name='clearfolio' -F number=264 \
  -f query='
query($owner: String!, $name: String!, $number: Int!) {
  repository(owner: $owner, name: $name) {
    pullRequest(number: $number) {
      reviewThreads(first: 100) {
        nodes {
          isResolved
          comments(first: 1) { nodes { author { login } path line body } }
        }
      }
    }
  }
}' \
  --jq '.data.repository.pullRequest.reviewThreads.nodes[]
    | select(.isResolved == false)
    | [.comments.nodes[0].author.login, .comments.nodes[0].path, (.comments.nodes[0].line | tostring), .comments.nodes[0].body]
    | `@tsv`' || true

echo '== Current PR review and merge state =='
gh pr view 264 --repo "$repo" \
  --json headRefOid,mergeStateStatus,reviewDecision,latestReviews,statusCheckRollup

echo '== Available branch protection and rulesets =='
gh api "repos/$repo/branches/main/protection" || true
gh api "repos/$repo/rules/branches/main" || true
gh api "repos/$repo/rulesets?includes_parents=true" || true

echo '== Exact-head check state summary =='
gh api "repos/$repo/commits/$head/check-runs?per_page=100" --paginate \
  --jq '.check_runs[]
    | select(.name == "Maven test" or .name == "strix" or .name == "Semgrep (multi-language SAST)" or .name == "osv-scan" or (.name | startswith("fuzz")) or (.name | startswith("Analyze")))
    | [.name,.status,.conclusion]
    | `@tsv`'

Length of output: 56758


@seonghobae Review complete for exact head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a.

I found no source-level blocker.

  • setBusyState uses WeakMap state and depth counting.
  • Each restore callback is idempotent.
  • The helper restores state only after the final restore call.
  • The helper preserves child-node identity with Array.from(button.childNodes) and replaceChildren(...).
  • The helper restores the original disabled, aria-busy, and aria-label values. It distinguishes absent and empty ARIA values.
  • Details, Status JSON, and Open viewer have document-specific accessible names.
  • Status JSON applies setBusyState(btn, "Loading status JSON...") before asynchronous work. Its .finally(restore) call restores the original state.
  • A disabled native button prevents repeated user activation while the JSON request is pending.
  • The integration test verifies the operation-specific pending name, disabled state, aria-busy, restored state, inert markup-like filename text, popup opener isolation, and JSON rendering.
  • Maven runs the Node DOM tests during test.
  • Maven requires 100% line, branch, and function coverage for src/main/resources/static/assets/viewer/dom-utils.js.
  • CI uses Node.js 24 and a full-SHA actions/setup-node pin.
  • The checked workflow inventory contains no reconciliation workflow or write-scoped workflow indicator.
  • Exact-head Maven, Semgrep, OSV scan, Strix, CodeQL, and all fuzz checks succeeded.
  • The review-thread query found no unresolved threads.

I cannot approve this pull request yet. GitHub reports BLOCKED and REVIEW_REQUIRED. The repository ruleset requires one approving repository review, and latestReviews contains no approval. The branch-protection REST endpoint returned HTTP 403, so I could not inspect its complete configuration.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@seonghobae
seonghobae marked this pull request as draft August 6, 2026 02:58
auto-merge was automatically disabled August 6, 2026 02:58

Pull request was converted to draft

Copy link
Copy Markdown
Collaborator Author

Dependency-order correction: this PR is now Draft so it cannot auto-merge ahead of authoritative security parent #270. Both slices modify shared pom.xml, CI, and CHANGELOG.md; allowing #264 to merge first would invalidate #270's current synthetic-merge and generated-evidence assumptions and force avoidable reconciliation.

After #270 integrates, rebuild or reconcile this same bounded accessibility implementation onto the resulting protected main, preserve the WeakMap nested/idempotent busy-state and exact DOM/ARIA restoration contract, and rerun exact-head CI, Security Scan, SAST, fuzz, CodeRabbit/OpenCode/Noema/Strix, zero unresolved threads, and counted independent approval. Previous head 718107a7a6eaca15a1f3e33ea7ceebefaf23d85a remains provenance, not post-parent merge evidence. Do not re-enable auto-merge before that reconciliation.

@seonghobae
seonghobae force-pushed the fix/accessible-async-viewer-controls branch from 718107a to 0326f8f Compare August 6, 2026 03:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants